Skip to content

Method: executeAskQuery(Query, Statement.StatementOntology)

1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.ontodriver.jena.connector;
16:
17: import cz.cvut.kbss.ontodriver.Statement.StatementOntology;
18: import cz.cvut.kbss.ontodriver.config.DriverConfiguration;
19: import cz.cvut.kbss.ontodriver.jena.exception.JenaDriverException;
20: import cz.cvut.kbss.ontodriver.jena.query.AbstractResultSet;
21: import cz.cvut.kbss.ontodriver.jena.query.AskResultSet;
22: import cz.cvut.kbss.ontodriver.jena.query.SelectResultSet;
23: import org.apache.jena.query.*;
24: import org.apache.jena.rdf.model.*;
25: import org.apache.jena.system.Txn;
26: import org.apache.jena.update.UpdateAction;
27:
28: import java.util.ArrayList;
29: import java.util.Collection;
30: import java.util.Iterator;
31: import java.util.List;
32:
33: /**
34: * Main storage connector using the {@link cz.cvut.kbss.ontodriver.jena.config.JenaOntoDriverProperties#READ_COMMITTED}
35: * connector strategy.
36: * <p>
37: * Adding statements to it actually adds them to the repository.
38: * <p>
39: * Note on transactions:
40: * <p>
41: * Starting a transaction on this connector also starts a write transaction on the underlying dataset. Commit then
42: * commits the transaction. Therefore, these transactions should be short. Reading can happen in parallel (as per Jena
43: * documentation).
44: */
45: public class SharedStorageConnector extends AbstractStorageConnector {
46:
47: SharedStorageConnector(DriverConfiguration configuration) {
48: super(configuration);
49: }
50:
51: @Override
52: void initialize() {
53: this.storage = Storage.create(configuration);
54: }
55:
56: @Override
57: public synchronized void begin() {
58: ensureOpen();
59: transaction.begin();
60: storage.begin(ReadWrite.WRITE);
61: }
62:
63: @Override
64: public synchronized void commit() throws JenaDriverException {
65: ensureTransactionalState();
66: transaction.commit();
67: storage.writeChanges();
68: storage.commit();
69: transaction.afterCommit();
70: }
71:
72: void ensureTransactionalState() {
73: ensureOpen();
74: transaction.verifyActive();
75: }
76:
77: @Override
78: public void rollback() {
79: ensureOpen();
80: transaction.rollback();
81: storage.rollback();
82: transaction.afterRollback();
83: }
84:
85: @Override
86: public Collection<Statement> find(Resource subject, Property property, RDFNode value, String context) {
87: ensureOpen();
88: return Txn.calculateRead(storage.getDataset(), () -> {
89: final Model target = context != null ? storage.getNamedGraph(context) : storage.getDefaultGraph();
90: final StmtIterator it = target.listStatements(subject, property, value);
91: return it.toList();
92: });
93: }
94:
95: @Override
96: public boolean contains(Resource subject, Property property, RDFNode value, String context) {
97: ensureOpen();
98: return Txn.calculateRead(storage.getDataset(), () -> {
99: final Model target = context != null ? storage.getNamedGraph(context) : storage.getDefaultGraph();
100: return target.contains(subject, property, value);
101: });
102: }
103:
104: @Override
105: public List<String> getContexts() {
106: ensureOpen();
107: final Iterator<String> it = Txn.calculateRead(storage.getDataset(), () -> storage.getDataset().listNames());
108: final List<String> contexts = new ArrayList<>();
109: it.forEachRemaining(contexts::add);
110: return contexts;
111: }
112:
113: @Override
114: public void add(List<Statement> statements, String context) {
115: ensureTransactionalState();
116: storage.add(statements, context);
117: }
118:
119: @Override
120: public void remove(List<Statement> statements, String context) {
121: ensureTransactionalState();
122: storage.remove(statements, context);
123: }
124:
125: @Override
126: public void remove(Resource subject, Property property, RDFNode object, String context) {
127: ensureTransactionalState();
128: if (context != null) {
129: storage.remove(storage.getNamedGraph(context).listStatements(subject, property, object), context);
130: } else {
131: storage.remove(storage.getDefaultGraph().listStatements(subject, property, object), null);
132: }
133: }
134:
135: @Override
136: public AbstractResultSet executeSelectQuery(Query query, StatementOntology target) throws JenaDriverException {
137: ensureOpen();
138: try {
139: QueryExecution exec = QueryExecutionFactory.create(query, storage.getDataset());
140: final org.apache.jena.query.ResultSet rs = exec.execSelect();
141: // The QueryExecution is closed by the SelectResultSet (so that it has access to the results)
142: return new SelectResultSet(exec, rs);
143: } catch (RuntimeException e) {
144: throw queryFailed(query, e);
145: }
146: }
147:
148: private static JenaDriverException queryFailed(Object query, RuntimeException e) {
149: return new JenaDriverException("Execution of query " + query + " failed.", e);
150: }
151:
152: @Override
153: public AbstractResultSet executeAskQuery(Query query, StatementOntology target) throws JenaDriverException {
154: ensureOpen();
155: try (final QueryExecution exec = QueryExecutionFactory.create(query, storage.getDataset())) {
156: return new AskResultSet(exec.execAsk());
157: } catch (RuntimeException e) {
158: throw queryFailed(query, e);
159: }
160: }
161:
162: @Override
163: public void executeUpdate(String query, StatementOntology target) throws JenaDriverException {
164: ensureOpen();
165: try {
166: UpdateAction.parseExecute(query, storage.getDataset());
167: } catch (RuntimeException e) {
168: throw queryFailed(query, e);
169: }
170: }
171:
172: @Override
173: public synchronized void close() {
174: if (!isOpen()) {
175: return;
176: }
177: if (storage != null) {
178: storage.close();
179: }
180: super.close();
181: }
182:
183: /**
184: * Reloads data from the underlying storage (if possible).
185: * <p>
186: * Note that this applies only to RDF file-based storage access, other storage do not support reloading.
187: */
188: public synchronized void reloadStorage() {
189: ensureOpen();
190: storage.reload();
191: }
192:
193: /**
194: * Sets new dataset on the underlying storage.
195: * <p>
196: * Note that this is supported only for in-memory storage.
197: *
198: * @param dataset The dataset to use
199: */
200: public synchronized void setDataset(Dataset dataset) {
201: ensureOpen();
202: storage.setDataset(dataset);
203: }
204: }